<?php declare(strict_types=1);
/**
 * @author      xianganyall <xianganyall@gmail.com>
 * @copyright   2023-2025 owner
 **/

namespace Srv\Apps\Socks\Index;

use Srv\Apps\Proto\DTO\Socks\AckNumDTO;
use Srv\Apps\Proto\DTO\Socks\SubscribeKeyDTO;
use Srv\Apps\Proto\DTO\Socks\SubscribeKeySendBinaryDTO;
use Srv\Apps\Proto\DTO\Socks\SubscribeKeySendTextDTO;
use Srv\Apps\Proto\Enum\ErrCodeEnum;
use Srv\Apps\Proto\Enum\LangKeyEnum;
use Srv\Apps\Proto\VO\Socks\SubscribeListVO;
use Srv\Apps\Socks\Index\Ctl\IndexSocksCtl;
use Srv\Libs\ConfModel\RouteConfData;
use Srv\Libs\Frame\ActionAbstract;
use Srv\Libs\Frame\DTOAbstract;
use Srv\Libs\Frame\Lang;
use Srv\Libs\Frame\ResponseData;
use Srv\Libs\Frame\VOAbstract;
use Srv\Libs\Frame\WebSocketTable;

final class IndexSocksAct extends ActionAbstract
{
    /**
     * @url /index
     * @auth NULL
     * @flag HIDE
     * 默认Index
     */
    public function index(RouteConfData $RouteConfData, ?DTOAbstract $DTOClass, ?VOAbstract $VOClass):bool
    {
        unset($RouteConfData, $DTOClass);
        return ResponseData::rspSuccAuto('', $VOClass);
    }

    /**
     * @url /ping
     * @auth NULL
     * @rsp
     * ping
     */
    public function ping(RouteConfData $RouteConfData, ?DTOAbstract $DTOClass, ?VOAbstract $VOClass):bool
    {
        unset($RouteConfData, $DTOClass);
        return ResponseData::rspSuccAuto('', $VOClass);
    }

    /**
     * @url /ack
     * @auth NULL
     * @req Srv.Apps.Proto.DTO.Socks.AckNumDTO
     * 发送ack回复
     */
    public function ack(RouteConfData $RouteConfData, ?DTOAbstract $DTOClass, ?VOAbstract $VOClass):bool
    {
        unset($RouteConfData, $VOClass);
        if(!($DTOClass instanceof AckNumDTO)) return ResponseData::rspErrAuto(ErrCodeEnum::ERR_SYS_PARAMS_ERROR, Lang::get(LangKeyEnum::LANG_SYS_PARAMS_ERROR));
        WebSocketTable::delAckNum($DTOClass->getWsAckNum()-1);
        return ResponseData::rspNoPush();
    }

    /**
     * @url /subscribe/list
     * @auth NULL
     * @rsp Srv.Apps.Proto.VO.Socks.SubscribeListVO
     * 获取订阅KEY列表
     */
    public function subscribeList(RouteConfData $RouteConfData, ?DTOAbstract $DTOClass, ?VOAbstract $VOClass):bool
    {
        unset($RouteConfData, $DTOClass);
        if(!($VOClass instanceof SubscribeListVO)) return ResponseData::rspErrAuto(ErrCodeEnum::ERR_ERROR, Lang::get(LangKeyEnum::LANG_ERROR));
        $IndexSocksCtl          = IndexSocksCtl::tag();
        $socketFd               = self::getWebSocketFd();
        if(!$IndexSocksCtl->subscribeList($socketFd, $VOClass)){
            return ResponseData::rspErrAuto(ErrCodeEnum::ERR_FAIL, Lang::get(LangKeyEnum::LANG_FAILED));
        }
        return ResponseData::rspSuccAuto('', $VOClass);
    }

    /**
     * @url /subscribe/set
     * @auth NULL
     * @req Srv.Apps.Proto.DTO.Socks.SubscribeKeyDTO
     * 设置订阅KEY
     */
    public function subscribeSet(RouteConfData $RouteConfData, ?DTOAbstract $DTOClass, ?VOAbstract $VOClass):bool
    {
        unset($RouteConfData, $VOClass);
        if(!($DTOClass instanceof SubscribeKeyDTO)) return ResponseData::rspErrAuto(ErrCodeEnum::ERR_SYS_PARAMS_ERROR, Lang::get(LangKeyEnum::LANG_SYS_PARAMS_ERROR));
        $subKeyList             = $DTOClass->toArrayList($DTOClass->getSubKeyList());
        $IndexSocksCtl          = IndexSocksCtl::tag();
        $socketFd               = self::getWebSocketFd();
        if(!$IndexSocksCtl->subscribeSet($socketFd, $subKeyList)){
            return ResponseData::rspErrAuto(ErrCodeEnum::ERR_FAIL, Lang::get(LangKeyEnum::LANG_FAILED));
        }
        return ResponseData::rspSuccAuto();
    }

    /**
     * @url /subscribe/add
     * @auth NULL
     * @req Srv.Apps.Proto.DTO.Socks.SubscribeKeyDTO
     * 添加订阅KEY
     */
    public function subscribeAdd(RouteConfData $RouteConfData, ?DTOAbstract $DTOClass, ?VOAbstract $VOClass):bool
    {
        unset($RouteConfData, $VOClass);
        if(!($DTOClass instanceof SubscribeKeyDTO)) return ResponseData::rspErrAuto(ErrCodeEnum::ERR_SYS_PARAMS_ERROR, Lang::get(LangKeyEnum::LANG_SYS_PARAMS_ERROR));
        $subKeyList             = $DTOClass->toArrayList($DTOClass->getSubKeyList());
        $IndexSocksCtl          = IndexSocksCtl::tag();
        $socketFd               = self::getWebSocketFd();
        if(!$IndexSocksCtl->subscribeAdd($socketFd, $subKeyList)){
            return ResponseData::rspErrAuto(ErrCodeEnum::ERR_FAIL, Lang::get(LangKeyEnum::LANG_FAILED));
        }
        return ResponseData::rspSuccAuto();
    }

    /**
     * @url /subscribe/del
     * @auth NULL
     * @req Srv.Apps.Proto.DTO.Socks.SubscribeKeyDTO
     * 删除订阅KEY
     */
    public function subscribeDel(RouteConfData $RouteConfData, ?DTOAbstract $DTOClass, ?VOAbstract $VOClass):bool
    {
        unset($RouteConfData, $VOClass);
        if(!($DTOClass instanceof SubscribeKeyDTO)) return ResponseData::rspErrAuto(ErrCodeEnum::ERR_SYS_PARAMS_ERROR, Lang::get(LangKeyEnum::LANG_SYS_PARAMS_ERROR));
        $subKeyList             = $DTOClass->toArrayList($DTOClass->getSubKeyList());
        $IndexSocksCtl          = IndexSocksCtl::tag();
        $socketFd               = self::getWebSocketFd();
        if(!$IndexSocksCtl->subscribeDel($socketFd, $subKeyList)){
            return ResponseData::rspErrAuto(ErrCodeEnum::ERR_FAIL, Lang::get(LangKeyEnum::LANG_FAILED));
        }
        return ResponseData::rspSuccAuto();
    }

    /**
     * @url /subscribe/send/text
     * @auth NULL
     * @req Srv.Apps.Proto.DTO.Socks.SubscribeKeySendTextDTO
     * 发送文本内容到订阅KEY列表
     */
    public function subscribeSendText(RouteConfData $RouteConfData, ?DTOAbstract $DTOClass, ?VOAbstract $VOClass):bool
    {
        unset($RouteConfData, $VOClass);
        if(!($DTOClass instanceof SubscribeKeySendTextDTO)) return ResponseData::rspErrAuto(ErrCodeEnum::ERR_SYS_PARAMS_ERROR, Lang::get(LangKeyEnum::LANG_SYS_PARAMS_ERROR));
        $subKeyList             = $DTOClass->toArrayList($DTOClass->getSubKeyList());
        $text                   = $DTOClass->getText();
        $IndexSocksCtl          = IndexSocksCtl::tag();
        $socketFd               = self::getWebSocketFd();
        if(!$IndexSocksCtl->subscribeSendText($socketFd, $subKeyList, $text)){
            return ResponseData::rspErrAuto(ErrCodeEnum::ERR_FAIL, Lang::get(LangKeyEnum::LANG_FAILED));
        }
        return ResponseData::rspSuccAuto();
    }

    /**
     * @url /subscribe/send/binary
     * @auth NULL
     * @req Srv.Apps.Proto.DTO.Socks.SubscribeKeySendBinaryDTO
     * 发送二进制内容到订阅KEY列表
     */
    public function subscribeSendBinary(RouteConfData $RouteConfData, ?DTOAbstract $DTOClass, ?VOAbstract $VOClass):bool
    {
        unset($RouteConfData, $VOClass);
        if(!($DTOClass instanceof SubscribeKeySendBinaryDTO)) return ResponseData::rspErrAuto(ErrCodeEnum::ERR_SYS_PARAMS_ERROR, Lang::get(LangKeyEnum::LANG_SYS_PARAMS_ERROR));
        $subKeyList             = $DTOClass->toArrayList($DTOClass->getSubKeyList());
        $binary                 = $DTOClass->getBinary();
        $IndexSocksCtl          = IndexSocksCtl::tag();
        $socketFd               = self::getWebSocketFd();
        if(!$IndexSocksCtl->subscribeSendBinary($socketFd, $subKeyList, $binary)){
            return ResponseData::rspErrAuto(ErrCodeEnum::ERR_FAIL, Lang::get(LangKeyEnum::LANG_FAILED));
        }
        return ResponseData::rspSuccAuto();
    }
}